You can treat this as a graph problem. Convert your grid to a graph, where each vertex represents a cell in the grid, and the edges between vertices represent valid movements between these cells.
From there, you can use the following recursive algorithm to determine if a word S can be found in the graph G:
FindWord(G, S):
1. Set C to the first letter of S.
2. Set S' to S with the first letter removed.
3. For all vertices V in G:
3.1. If the letter in V is not C, continue to the next vertex.
3.2. If CheckPaths(G, S', V, {}) returns true, return true.
4. Return false.
CheckPaths(G, S, V, Visited):
1. If S is empty, return true.
2. Set C to the first letter of S.
3. Set S' to S with the first letter removed.
4. Set Visited' to Visited ∪ {V}.
5. For all cells V' connected to V:
5.1. If V' ∈ Visited, continue to the next vertex.
5.2. If the letter in V' is not C, continue to the next vertex.
5.3. If CheckPaths(G, S', V', Visited') returns true, return true.
6. Return false.
The actual implementation will likely be a bit different (for example, it might be a good idea to not make a copy of Visited, but share a single set by removing vertices after determining a path failed), but this is the basic idea of how to do it.