Это не так просто, как вы думаете. Предыдущие ответы потерпят неудачу во многих ситуациях. Вот тот, который должен заменить каждое слово $, которое уже не находится внутри []:
$text = preg_replace('/\G((?:[^\[]|\[[^\]]*\])*?)('.$word.')/', '$1[$2]($2)', $text)
Если $ word содержит специальные символы регулярного выражения, вы можете захотеть preg_quote
it.
Пример
$text = 'aa foo bb [foo bar](http://example.com) cc foo dd';
$word = 'foo';
$text = preg_replace('/\G((?:[^\[]|\[[^\]]*\])*?)('.$word.')/', '$1[$2]($2)', $text);
echo $text;
Выход:
aa [foo](foo) bb [foo bar](http://example.com) cc [foo](foo) dd