kb = Reverse @
TakeList[Characters["1234567890qwertyuiopasdfghjklzxcvbnm"], {10, 10, 9, 7}];
vLabels = Join @@
MapIndexed[{1, Sqrt[3]/2} Reverse@#2 - {(#2[[1]] - 1)/2, 0} -> # &, kb, {2}];
qwertyGraph =
VertexReplace[#, vLabels] & @
NearestNeighborGraph[Keys @ vLabels,
VertexLabels -> Placed["Name", Center],
VertexSize -> Large,
VertexLabelStyle -> 14]

VertexComponent[qwertyGraph, "t", 1]
{"t", "f", "g", "r", "y", "5", "6"}
VertexComponent[qwertyGraph, "b", 1]
{"b", "v", "n", "g", "h"}
Select[DictionaryWordQ] @
MapApply[StringJoin] @
Tuples @
Map[VertexComponent[qwertyGraph, #, 1] &] @
Characters["hello"]
{"hello", "brook", "jello"}
EDIT by OP
With the dictionary available and the task enunciated in the post mentioned in the comments:
Clear[adjChecker];
adjChecker[k_String] :=
And @@ (MemberQ[VertexComponent[qwertyGraph, #2, 1], #1] & @@@
Partition[Characters@k, 2, 1])
Select[DictionaryLookup[], adjChecker] // SortBy[StringLength]
{"a", "I", "as", "dc", "er", "es", "lo", "oi", "re", "uh", "we",
"ass", "awe", "dew", "ere", "err", "ewe", "huh", "loo", "lop", "oik",
\ "poi", "pol", "pop", "red", "saw", "see", "sew", "was", "wed",
"wee", \ "WWW", "awed", "awes", "deed", "deer", "dews", "drew",
"ewer", \ "ewes", "free", "kook", "loll", "look", "loop", "plop",
"poll", \ "polo", "pool", "poop", "reds", "reed", "sass", "saws",
"seed", \ "seer", "sees", "sere", "serf", "sews", "tree", "weds",
"weed", \ "weer", "wees", "were", "asses", "deeds", "deres", "dress",
"erred", \ "freed", "freer", "frees", "reeds", "resew", "rewed",
"sawed", \ "seeds", "sered", "serer", "seres", "sewed", "sewer",
"swede", \ "treed", "trees", "tress", "trews", "wases", "weeds",
"assert", \ "assess", "deeded", "desert", "lollop", "qwerty",
"redder", "redrew", \ "reseed", "resews", "reweds", "sassed",
"sasses", "seeded", "seeder", \ "seesaw", "swedes", "wedded",
"wedder", "weeded", "weeder", \ "dessert", "dressed", "dresser",
"dresses", "redress", "reseeds", \ "resewed", "seesaws", "tresses",
"assessed", "assesses", "reseeded", \ "rewedded", "seesawed",
"redressed", "redresses"}
ImageContentsandImageCasesseemed promising to me, but we'd need an entity concept for "letter" or "alphabetic character" or something like that. Both functions (without the qualifier as a second argument) find the keyboard and nothing else. I don't know if that means it can't possibly find anything else, or if it would use a different search strategy if we could tell it to look for "letter". Anyway, if we could find the letters this way, then you can find their location and use a distance function etc etc. – lericr Nov 03 '23 at 17:06TextRecognizebefore giving up. I will wait; perhaps someone has a method they want to share. @azerbajdzan – Syed Nov 04 '23 at 10:51ds = Dataset[ TextRecognize[Binarize@ImageResize[img, 3000], "Character", {"Text", "BoundingBox", "Image"}, RecognitionPrior -> "Column"], MaxItems -> All]? – kglr Nov 04 '23 at 13:41