Use a trie with DFS for wildcard handling.
Add words normally to the trie.
For search: traverse the trie character by character. When you see a ., try all children (branching). If you reach the end of the pattern and the trie node is marked as a word ending, return true.
The DFS explores all possible matches for wildcards while still pruning impossible paths.