Here's an important real-world example use-case for strtr where str_replace will not work or will introduce obscure bugs:
<?php
$strTemplate = "My name is :name, not :name2.";
$strParams = [
':name' => 'Dave',
'Dave' => ':name2 or :password', ':name2' => 'Steve',
':pass' => '7hf2348', ];
echo strtr($strTemplate, $strParams);
echo str_replace(array_keys($strParams), array_values($strParams), $strTemplate);
?>
Any time you're trying to template out a string and don't necessarily know what the replacement keys/values will be (or fully understand the implications of and control their content and order), str_replace will introduce the potential to incorrectly match your keys because it does not expand the longest keys first.
Further, str_replace will replace in previous replacements, introducing potential for unintended nested expansions. Doing so can put the wrong data into the "sub-template" or even give users a chance to provide input that exposes data (if they get to define some of the replacement strings).
Don't support recursive expansion unless you need it and know it will be safe. When you do support it, do so explicitly by repeating strtr calls until no more expansions are occurring or a sane iteration limit is reached, so that the results never implicitly depend on order of your replacement keys. Also make certain that any user input will expanded in an isolated step after any sensitive data is already expanded into the output and no longer available as input.
Note: using some character(s) around your keys to designate them also reduces the possibility of unintended mangling of output, whether maliciously triggered or otherwise. Thus the use of a colon prefix in these examples, which you can easily enforce when accepting replacement input to your templating/translation system.