JavaScript Trie + DFS
\nclass TrieNode {\n    constructor(value, isWord = false) {\n        this.value = value;\n        this.isWord = isWord;\n        this.children = {};\n    }\n  
```\nclass TrieNode {\n    constructor(value, isWord = false) {\n        this.value = value;\n        this.isWord = isWord;\n        this.children = {};\n    }\n    \n    addChild(value, isWord) {\n        if (this.children[value]) {\n            const node = this.children[value];\n            node.isWord = node.isWord || isWord;\n            return node;\n        }\n\n        const node = new TrieNode(value, isWord);\n        this.children[value] = node;\n        return node;\n    }\n}\n\nclass Trie {\n    constructor() {\n        this.root = new TrieNode(\'*\');\n    }\n    \n    addWord(word, callback) {\n        let node = this.root;\n\n        for (let i = 0; i < word.length; i++) {\n            node = node.addChild(word[i], i === word.length - 1);\n        }\n    }\n    \n    dfs(callback) {\n        return this._dfs(callback, this.root, \'\');\n    }\n    \n    _dfs(callback, node, s) {\n        Object\n            .values(node.children)\n            .forEach(child => {\n                if (child.isWord) {\n                    callback(s + child.value);\n                    this._dfs(callback, child, s + child.value);\n                }\n            });\n    }\n}\n\n/**\n * @param {string[]} words\n * @return {string}\n */\nvar longestWord = function(words) {\n    const trie = new Trie();\n\n    for (const word of words) {\n        trie.addWord(word);\n    }\n\n    let longest = \'\';\n\n    trie.dfs(word => {\n        if (word.length < longest.length) return;\n\n        longest = word.length > longest.length ? word : word < longest ? word : longest;\n    });\n\n    return longest;\n};\n```
[]