The one thing the docs bury
Body.replaceText(searchPattern, replacement) is the right method, and it works on the entire body including headers if you use the full document range. What the official reference mentions only briefly is that searchPattern is a Java-flavored regular expression, not a plain string. That distinction is invisible when your search term is something like 'John Smith', but it will ruin your day the moment your template uses dots, brackets, or dollar signs.
The first time I hit this, I was replacing version strings like 'v1.0' across a doc and ended up replacing 'v100' and 'v1X0' as well — because the unescaped dot matched any character. The fix is a double backslash before each special character inside the JavaScript string: 'v1\.0' becomes the regex v1\.0, which matches only a literal dot.