Your logic currently does a lot more work that it needs to do.

First, you are iterating every element in DOM and then iterating on every child element of those (which is actually duplicate work, since all nested tags would already be present in `elements`). This is especially problematic in that you are really only interested in text nodes.  So, your first order of business, is to get only those nodes you care about.

Perhaps check out this StackOverflow post on this topic - http://stackoverflow.com/questions/10730309/find-all-text-nodes-in-html-page.

I personally like the TreeWalker approach in the accepted answer.

Now that you have a good flattened representation of these text nodes, you can just iterate through and directly modify them.

    // build word map
    var wordMap = {
       'match value': 'replace value',
       // etc.
    }
    
    // build single regex
    var regex = new RegExp(Object.keys(wordMap).join("|"),"gi");

    // get text nodes
    var textNodes = ...; // derive similar to linked SO question above.
    
    // iterate text nodes and modify in place
    for (var i = 0, len = textNodes.length; i < len; i++) {
        textNodes[i].nodeValue = textNodes[i].nodeValue.replace(regex, function(match) {
            return wordMap[match];
        });
    }

This example above would have you modifying the nodes in place rather than having to do any DOM replacements.