Например: 16 букв = 4*4, 20 букв = 4*5 и т.д. То есть, иметь возможность опционально указать пропорции сетки в зависимости от количества букв.
Квадратный корень из количества букв или ближайший извлекаемый квадратный корень из заданного числа (модульная разница которого меньше):
Условие: [общее кол-во букв = 20 ] <= x^2,
т.е. мы хотим поместить слова в максимально-квадратную область.
проверяем: x=2 => x^2=4 => мало.
проверяем: x=3 => x^2=9 => мало.
проверяем: x=4 => x^2=16 => мало.
проверяем: x=5 => x^2=25 => много. стоп.
Теперь, сравниваем:
abs(20-4^2)=4 < abs(20-5^2)=5
Т.е., мы выбираем максимальное приближение к искомому, а именно, число 4 и квадрат 4x4.
Затем, "довешиваем" (удлиняем) одну сторону квадрата до нужного числа (делаем прямоугольник), кратного перемножению короткой грани на только что созданную удлинённую на столько, чтобы могли поместиться все буквы.
Вот и будет как раз сетка: 4x5 (4x4+4=20)
Затем, заполняете всё нужными словами, а то, что останется - заполняете словом, с нужным (оставшимся) количеством букв.
Если возможно нужно как-то растянуто, но главное - чтобы всё влезло "впритык", то можно сразу искать через покрываемую площадь: S=X*Y и минимальную длину стороны, кратную числу всех букв и уже от этого отталкиваться...
Т.е., конечная задача найти НОД для пар значений: S и X, и для S и Y, где S нужное кол-во букв для всех слов.
Если число букв простое - то делается так же, как написано выше: ближайшим дополнением до произведения X*Y, превышающего общее кол-во букв на как можно меньшее количество добавочных клеток сетки (правда проще - найти нужное по размеру слово и заменить им короткое, или всегда следить за НУЖНОЙ кратностью суммарного числа всех букв в словах).
Укладывать слова в сетку можно по-спирали из любой точки внешнего периметра до полного кольца и затем, смещение к центру на 1 клетку и снова в том же направлении.