Write a D*mn Unambiguous Censor Censors are a common tool used on the interwebs. But they often censor too much of the word, and thus make the cursing ambiguous to the reader. And sometimes they don't censor enough, so the words still remain offending. Your task is to fix that.
Your task
Write a program/function/whatever that takes two lists and a string. The first list will be the dictionary of all words in your language like: [&quot;hello&quot;, &quot;goodbye&quot;, &quot;belgium&quot;, &quot;offensive&quot;, &quot;jumping&quot;, &quot;hypercool&quot;]. The next will be subset of the first list containing all of the offensive words in the language: [&quot;belgium&quot;, &quot;offensive&quot;]. The words in these lists are guaranteed to contain only lowercase letters of the alphabet.
The string is the phrase you will have to censor. It will be made of words from the dictionary, separated by spaces: &quot;Goodbye offensive belgium&quot;
The return value will be that phrase censored. However, you have to censor in a certain way. Specifically, for each word in the offensive list, you have to censor as many letters as possible while remaining completely unambiguous in the main dictionary. So here it would be: Goodbye o******** b******.
Clarifications

Your code has to interpret the words case-insensitively, but return with the initial capitalization.
If there are multiple optimal answers, pick any of them.
If unambiguous censoring is impossible, censor a single letter that has the least number of other possible interpretations (If multiple are possible, again, its your choice).

Test Cases
[&quot;hello&quot;, &quot;goodbye&quot;, &quot;belgium&quot;, &quot;offensive&quot;, &quot;jumping&quot;, &quot;hypercool&quot;] [&quot;belgium&quot;, &quot;offensive&quot;] &quot;Goodbye offensive belgium&quot; -&gt; &quot;Goodbye o******** b******&quot;
[&quot;word&quot;] [&quot;word&quot;] &quot;word&quot; -&gt; &quot;****&quot;
[&quot;hot&quot;, &quot;hat&quot;, &quot;bat&quot;, &quot;had&quot;] [&quot;hat&quot;] &quot;hat&quot; -&gt; &quot;*at&quot; or &quot;h*t&quot; or &quot;ha*&quot;
https://gist.github.com/deekayen/4148741 [&quot;quart&quot;] &quot;I am a quart&quot; -&gt; &quot;I am a q**r*&quot;

This is code-golf so shortest d*mn code in bytes wins!
P.S. Anyone caught the reference with belgium? ;P
JavaScript ES7, 194 bytes

(d,c,s,g=(a,b)=&gt;[...b].reduce((z,l,i)=&gt;z+(a[i]==l?1:0),0))=&gt;[for(s of s.split` `)~d.indexOf(s)?[...c[(x=[for(i of c)g(i,s)]).indexOf(Math.max(...x))]].map((l,i)=&gt;l!=s[i]?`*`:l).join``:s].join` `


A very large function. I'm guessing a few bytes can be golfed off but not much unless I completely change the way it works.