En realidad escribí un programa generador de crucigramas hace unos diez años (era enigmático pero las mismas reglas se aplicarían para crucigramas normales).
Tenía una lista de palabras (y pistas asociadas) almacenadas en un archivo ordenadas por uso descendente hasta la fecha (para que las palabras menos usadas estuvieran en la parte superior del archivo). Se elegía un template, básicamente una máscara de bits que representaba los cuadrados negros y libres, al azar de un conjunto proporcionado por el cliente.
Luego, para cada palabra incompleta en el rompecabezas (básicamente encontrar el primer cuadrado en blanco y ver si el de la derecha (palabra horizontal) o el de abajo (palabra vertical) también estaba en blanco), se hacía una búsqueda en el archivo en busca de la primera palabra que encajara, teniendo en cuenta las letras ya en esa palabra. Si no había una palabra que pudiera encajar, simplemente se marcaba toda la palabra como incompleta y se pasaba a la siguiente.
Al final habría algunas palabras incompletas que el compilador tendría que completar (y agregar la palabra y una pista al archivo si así lo deseaba). Si no podían encontrar ninguna idea, podrían editar el crucigrama manualmente para cambiar las restricciones o simplemente solicitar una regeneración total.
Una vez que el archivo de palabras/pistas alcanzó cierto tamaño (y se agregaban 50-100 pistas al día para este cliente), rara vez hubo más de dos o tres correcciones manuales que debían hacerse para cada crucigrama.