Updated answer
As a follow up question, can we apply a different strategy for distinguishing the words? For example, adding a frame instead of coloring them.
Answering the follow up question does bring better looking and easier to read results:
aResFr =
findwords[str, CommonWordQ,
<|Horizontal -> (Framed[Style[#, Blue, Bold],
Background -> Yellow] &),
Vertical -> (Framed[Style[#, Red], Background -> LightBlue] &),
Diagonal -> (Framed[Style[#, Purple, Bold],
Background -> GrayLevel[0.9]] &)|>];
Grid[#, Dividers -> All] & /@ aResFr

Grid[CombineHighlights[aResFr], Dividers -> All]

The update definitions below are based on the definitions of the first answer with some relatively small code refactoring. The function signatures have to be "relaxed" to take "highlighter function" as an argument.
Definitions
(*Declare the minimum length of a word*)
minWordLength = 3;
ClearAll[substrings];
substrings[str_String, len_ : minWordLength] :=
Block[{r = StringLength[str]},
Join @@ Table[StringTake[str, {i, j}], {i, r + 1}, {j, i + len - 1, r}]
];
ClearAll[wordsFinder];
wordsFinder[str_String, dictWordFunc_ : DictionaryWordQ,
highlighterFunc_ : (Style[#, Red] &)] :=
Block[{pos, res},
pos = Union @@ (Range @@ (Flatten[#, 1] &)@StringPosition[str, #] & /@
Select[substrings[str], dictWordFunc[#, IgnoreCase -> True] &]);
MapIndexed[If[MemberQ[pos, First@#2], highlighterFunc[#], #] &,
Characters@str]
];
ClearAll[highlightsDiag];
highlightsDiag[str_String, dictWordFunc_ : DictionaryWordQ,
highlighterFunc_ : (Style[#, Red] &)] :=
Block[{matChars, n, matInds, res},
matChars = Partition[Characters@str, Sqrt[StringLength[str]]];
n = Length[matChars];
matInds = Table[{i, j}, {i, n}, {j, n}];
res = Table[
AssociationThread[Diagonal[matInds, i],
wordsFinder[StringJoin @@ Diagonal[matChars, i], dictWordFunc,
highlighterFunc]], {i, -n + 1, n - 1}];
Normal[SparseArray[Normal[Join @@ res]]]
];
ClearAll[highlights];
highlights[str_String, dir_, dictWordFunc_ : DictionaryWordQ,
highlighterFunc_ : (Style[#, Red] &)] :=
Block[{matChars, n, matInds, res},
matChars = Partition[Characters@str, Sqrt[StringLength[str]]];
If[TrueQ[dir === Vertical],
matChars = Transpose[matChars]
];
n = Length[matChars];
matInds = Table[{i, j}, {i, n}, {j, n}];
res = Table[
AssociationThread[matInds[[i]],
wordsFinder[StringJoin @@ matChars[[i]], dictWordFunc,
highlighterFunc]], {i, n}];
res = Normal[SparseArray[Normal[Join @@ res]]];
If[TrueQ[dir === Vertical],
Transpose[res],
(*ELSE*)
res
]
] /; MemberQ[{Vertical, Horizontal}, dir];
ClearAll[findwords];
findwords[table_, dictWordFunc_ : DictionaryWordQ,
highlighterFunc_ : (Style[#, Red] &), opts : OptionsPattern[]] :=
Block[{str},
str = If[MatrixQ[table], StringJoin @@ Flatten[table], table];
str = ToUpperCase[str];
<|
"Horizontal" ->
highlights[str, Horizontal, dictWordFunc,
If[AssociationQ[highlighterFunc], highlighterFunc[Horizontal],
highlighterFunc]],
"Vertical" ->
highlights[str, Vertical, dictWordFunc,
If[AssociationQ[highlighterFunc], highlighterFunc[Vertical],
highlighterFunc]],
"Diagonal" ->
highlightsDiag[str, dictWordFunc,
If[AssociationQ[highlighterFunc], highlighterFunc[Diagonal],
highlighterFunc]]
|>
] /; (SquareMatrixQ[table] || StringQ[table]);
Clear[CombineHighlights];
CombineHighlights[aTbls_Association] :=
Map[If[VectorQ[#, StringQ], First[#], Last@Select[#, Not@*StringQ]] &,
Transpose[Values[aTbls], {3, 1, 2}], {2}];
Clear[CommonWordQ];
aCommonWords =
AssociationThread[ToLowerCase@Union[RandomWord["CommonWords", 10^6]],
True];
CommonWordQ[w_String, opts : OptionsPattern[]] :=
Lookup[aCommonWords, ToLowerCase@w, False];
First answer
Here are brief descriptions of my way of answering OP's questions:
We can define CommonWordQ
function based on RandomWord["CommonWords"]
.
One way to do it is to refactor OP's code:
Diagonal words highlights are similar to the horizontal and vertical words highlights finding, but using Diagonal
instead of Part
.
Note, that:
I tried to reuse OP's code, as much as possible.
I combine the tables into one, but the results are hard to read.
Further refactoring can put other Style
element, not just color.
The refactored functions take as arguments: string, is-it-a-word function, and color (or an association of colors).
Definitions
(*Declare the minimum length of a word*)
minWordLength = 3;
ClearAll[substrings];
substrings[str_String, len_ : minWordLength] :=
Block[{r = StringLength[str]},
Join @@
Table[StringTake[str, {i, j}], {i, r + 1}, {j, i + len - 1, r}]
];
ClearAll[wordsFinder];
wordsFinder[str_String, dictWordFunc_ : DictionaryWordQ, color_ : Red] :=
Block[{pos, res},
pos =
Union @@ (Range @@ (Flatten[#, 1] &)@StringPosition[str, #] & /@
Select[substrings[str],
dictWordFunc[#, IgnoreCase -> True] &]);
MapIndexed[If[MemberQ[pos, First@#2], Style[#, color], #] &,
Characters@str]
] /; ColorQ[color];
ClearAll[highlightsDiag];
highlightsDiag[str_String, dictWordFunc_ : DictionaryWordQ, color_ : Red] :=
Block[{matChars, n, matInds, res},
matChars = Partition[Characters@str, Sqrt[StringLength[str]]];
n = Length[matChars];
matInds = Table[{i, j}, {i, n}, {j, n}];
res =
Table[AssociationThread[Diagonal[matInds, i],
wordsFinder[StringJoin @@ Diagonal[matChars, i], dictWordFunc,
color]], {i, -n + 1, n - 1}];
Normal[SparseArray[Normal[Join @@ res]]]
] /; ColorQ[color];
ClearAll[highlights];
highlights[str_String, dir_, dictWordFunc_ : DictionaryWordQ, color_ : Red] :=
Block[{matChars, n, matInds, res},
matChars = Partition[Characters@str, Sqrt[StringLength[str]]];
If[TrueQ[dir === Vertical],
matChars = Transpose[matChars]
];
n = Length[matChars];
matInds = Table[{i, j}, {i, n}, {j, n}];
res =
Table[AssociationThread[matInds[[i]],
wordsFinder[StringJoin @@ matChars[[i]], dictWordFunc,
color]], {i, n}];
res = Normal[SparseArray[Normal[Join @@ res]]];
If[TrueQ[dir === Vertical],
Transpose[res],
(*ELSE*)
res
]
] /; MemberQ[{Vertical, Horizontal}, dir] && ColorQ[color];
ClearAll[findwords];
findwords[table_, dictWordFunc_ : DictionaryWordQ, color_ : Red, opts : OptionsPattern[]] :=
Block[{str},
str = If[MatrixQ[table], StringJoin @@ Flatten[table], table];
str = ToUpperCase[str];
<|
"Horizontal" ->
highlights[str, Horizontal, dictWordFunc,
If[ColorQ[color], color, color[1]]],
"Vertical" ->
highlights[str, Vertical, dictWordFunc,
If[ColorQ[color], color, color[2]]],
"Diagonals" ->
highlightsDiag[str, dictWordFunc,
If[ColorQ[color], color, color[3]]]
|>
] /; (SquareMatrixQ[table] || StringQ[table]);
Clear[CombineHighlights];
CombineHighlights[aTbls_Association] :=
Map[If[VectorQ[#, StringQ], First[#],
Last@Select[#, Head[#] === Style &]] &,
Transpose[Values[aTbls], {3, 1, 2}], {2}];
Clear[CommonWordQ];
aCommonWords = AssociationThread[ToLowerCase@Union[RandomWord["CommonWords", 10^6]], True];
CommonWordQ[w_String, opts : OptionsPattern[]] := Lookup[aCommonWords, ToLowerCase@w, False];
Tables for dictionary words
str = StringJoin@RandomChoice[CharacterRange["a", "z"], 256];
Grid[#, Dividers -> All] & /@ findwords[str, DictionaryWordQ, Red]

Tables for common words
Grid[#, Dividers -> All] & /@ findwords[str, CommonWordQ, Red]

Combining the tables
Combining the tables does not look that good (in my opinion):
aRes3 = findwords[str, CommonWordQ, <|1 -> Red, 2 -> Blue, 3 -> Green|>];
Grid[CombineHighlights[aRes3], Dividers -> All]

Diagonal[]
? $\endgroup$