Jingjing,
The new code you've written only follows the HtDP design recipe superficially.
First of all, none of your contracts actually tell me what the valid inputs and outputs of each function are. For instance, the contract for
build-position-to-neighbor is:
(listof lists) -> (hashof position to neighbors)
But this suggests to me that I could call it like this:
(build-position-to-neighbor (list (list "the" 'first "list") (list "list" 'number 2) (list (list (list)))))
After all, that argument is a list of lists. Nevertheless, that doesn't seem like what build-position-to-neighbor should actually accept. Your contracts need to be based on explicit data definitions. Descriptive phrases like "list of lists" or "hash of position to neighbors" are not precise enough.
Second, I think if you write data definitions for this program, you'll find something surprising: there are at least two different data definitions for a boggle board hidden in your functions. For a program that's all about processing a boggle board, you in fact manipulate many different kinds of lists and hash tables. It would be simpler, and more in the style of HtDP, to write a single data definition for a boggle board, and use that data definition for every function that operates on a boggle board.
Finally, your test cases are not particularly exhaustive. When testing a function, you should start with the smallest possible example. Write at least one base case test, at least one test for a single step beyond the base case, and at least one test larger than that. That way, when a test goes wrong, you don't just know that the function is broken, you have some idea how and why it is broken.