Trie + DFS Solution [C++]
\nclass TrieNode {\npublic:\n    bool isKey = false;\n    TrieNode* child[26];\n};\n\nclass Solution {\npublic:\n    TrieNode* root = new TrieNode();\n    \n   
```\nclass TrieNode {\npublic:\n    bool isKey = false;\n    TrieNode* child[26];\n};\n\nclass Solution {\npublic:\n    TrieNode* root = new TrieNode();\n    \n    void addWord (string word) {\n        TrieNode* curr = root;\n        for(char c : word) {\n            if(!curr->child[c - \'a\'])\n                curr->child[c - \'a\'] = new TrieNode();\n            curr = curr->child[c - \'a\'];\n        }\n        curr->isKey = true;\n    }\n    \n    bool search (string word, int index, int count) {\n        if(index >= word.size()) return count >= 2;\n        \n        TrieNode* curr = root;\n        \n        for(int i = index; i < word.size(); i++) {\n            char c = word[i];\n            if(!curr->child[c - \'a\'])\n                return false;\n            curr = curr->child[c - \'a\'];\n            if(curr->isKey) {\n                if(search(word, i + 1, count + 1))\n                    return true;\n            }\n        }\n        return false;\n    }\n    \n    vector<string> findAllConcatenatedWordsInADict (vector<string>& words) {\n        vector<string> res;\n        if(words.size() == 0) \n            return res;\n        for(string s : words)\n            addWord(s);\n        for(string s : words) {\n            if(search(s, 0, 0))\n                res.push_back(s);\n        }\n        return res;\n    }\n};\n```
['Depth-First Search', 'Trie', 'Recursion', 'C++']