Word break problem with dynamic programming
The first thing an algorithm needs to be is correct, and yours isn't, at least the recursive version (I didn't look at the second one).

For example, ContainsWordRecursive("ihate", dictionary) returns { "i" }, which I don't think is the right result. Instead, your method should somehow indicate that it failed, for example by returning null.