[Python]14 line DP with inline explanation
\nclass Solution:\n    def findAllConcatenatedWordsInADict(self, words: List[str]) -> List[str]:\n        \n        wordSet = set(words)\n        ans = []\n    
```\nclass Solution:\n    def findAllConcatenatedWordsInADict(self, words: List[str]) -> List[str]:\n        \n        wordSet = set(words)\n        ans = []\n        # 1) For each word w, For loop w[:i] \n        # 2) check if the front segment[0:j] is in wordSet and if the [j+1: i] is in the wordset\n        # EDGE CASE: cats is in wordSet but not concatenated, catsdog is in wordSet but also concatenated\n        # SOLUTION to edge case: instead of storing True/False, store the concatenated time, base is 1, and 2 means it is\n        # concatenated with "" + word, which is the word itself\n        # 3) If yes:w[:i] is concatenated=> dp[-1] > 2, append to ans, BREAK(to pass the edge case full of "a")\n        \n        for i, w in enumerate(words):\n            dp = [0] * (len(w) + 1)\n            dp[0] = 1\n            for i in range(1, len(w) + 1):\n                for j in range(i):\n                    if dp[j] and w[j: i] in wordSet:\n                        dp[i] = max(dp[i], dp[j] + 1)\n                        if dp[i] > 2:\n                            break\n            if dp[-1] > 2:\n                ans.append(w)\n        return ans\n        \n```
[]