Here is an approach similar to the one from KarelG.  It is different enough, though, to warrant its own answer.
Differences
- This one passes the ancestors as a parameter rather than keeping them as a free variable in the function.  Free variables make code harder to understand and much harder to test. 
- It separates out the recursive function from the public function, keeping them together in a closure.  This is a less common technique now that people are using some sort of module in many places, but it can still be useful, especially on the web.  That is the - (() => {/* ... return some function */ })()syntax.
 
- It uses a Set as the recursive accumulator, to avoid duplicates. 
- It ignores the gender.  I can't see a reason for checking it.  If the child says that the mother is so-and-so, I don't see any point to double-checking that `mother.sex === 'f'``.  I could be missing something here. 
- While it keeps the existing API of supplying a full person object and returning a list of names, it would be relatively easy to switch it to supplying just the names or to return a list of people.  More on that below. 
- I named it - allDescendentsas that seemed more accurate than- allChildren.
 
Code
const allDescendents = (() => {
  const all = (family, name, children = new Set()) => {
    const kids = family.filter(p => p.father === name || p.mother === name).map(k => k.name)
    kids.forEach(kid => (children.add(kid), all(family, kid, children)))
    return children
  }
  
  return (family, person) => Array.from(all(family, person.name))
})()
const bourbons = [ // https://en.wikipedia.org/wiki/Bourbon_family_tree
  {name: 'Philip III', sex: 'm', father: 'Louis IX', mother: 'Margaret'},
  {name: 'Robert', sex: 'm', father: 'Louis IX', mother: 'Margaret'},
  {name: 'Charles', sex: 'm', father: 'Philip III', mother: '?'},
  {name: 'Louis I', sex: 'm', father: 'Robert', mother: 'Beatrice'},
  {name: 'Philip IV', sex: 'm', father: 'Charles', mother: '?'},
  {name: 'Isabella', sex: 'f', father: 'Charles', mother: '?'},
  {name: 'Peter I', sex: 'm', father: 'Louis I', mother: 'Mary'},
  {name: 'James I', sex: 'm', father: 'Louis I', mother: 'Mary'},
  {name: 'John II', sex: 'm', father: 'Philip IV', mother: '?'},
  {name: 'Peter II', sex: 'm', father: 'James I', mother: 'Jeanne'},
  {name: 'John I', sex: 'm', father: 'James I', mother: 'Jeanne'},
  {name: 'Charles V', sex: 'm', father: 'John II', mother: '?'},
  {name: 'Joanna', sex: 'f', father: 'Peter I', mother: 'Isabella'},
  {name: 'Louis II', sex: 'f', father: 'Peter I', mother: 'Isabella'},
  {name: 'James II', sex: 'm', father: 'John I', mother: 'Catherine'},
  {name: 'Louis', sex: 'm', father: 'John I', mother: 'Catherine'},
  /* .. */
]
const louis1st = bourbons[3]
console.log(allDescendents(bourbons, louis1st))
 
 
Variants
This is factored in such a way as to make serious change fairly easy.  Most of these changes can also be combined.
Return a Set
It might make more sense to return a Set of values rather than an Array.  Presumably you do not want this collection to include duplicates.  A Set is the right data structure for that.  This solution uses a Set internally, and it's trivial to make that the public interface.  Just remove the call to Array.from:
-   return (family, person) => Array.from(all(family, person.name))
+   return (family, person) => all(family, person.name)
Supply a Name
Since you're returning a collection of names, perhaps it would be easier to supply a name for the input.  We can do this by altering the input parameter to receive the name:
-   return (family, person) => Array.from(all(family, person.name))
+   return (family, name) => Array.from(all(family, name))
Return People
Conversely, you might prefer to return the people objects directly.  A list of names is only so helpful.  A list containing the full Person object might be easier to work with.  This is what that would look like:
-  const all = (family, name, children = new Set()) => {
-    const kids = family.filter(p => p.father === name || p.mother === name).map(k => k.name)
+  const all = (family, person, children = new Set()) => {
+   const kids = family.filter(p => p.father === person.name || p.mother === person.name)
-  return (family, person) => Array.from(all(family, person.name))
+  return (family, person) => Array.from(all(family, person))
Avoiding Default Parameters
If the default parameters in the function bother you (red squiggles in your editor, for instance), then you can move the parameters to the exported function.  I like to keep the complexity in one place, which is why I have the defaults on the recursive function, but there is a good argument for simplifying the recursive function at the expense of the public function; it does make the recursive function somewhat easier to understand.
-   const all = (family, name, children = new Set()) => {
+   const all = (family, name, children) => {
-   return (family, person) => Array.from(all(family, person.name))
+   return (family, person) => Array.from(all(family, person.name, new Set()))
Making a module
Finally, we can easily turn this into a module.  If you are deploying to the browser, this will still require a build step, but it does simplify the code: Here is one version:
const all = (family, name, children = new Set()) => {
  const kids = family.filter(p => p.father === name || p.mother === name).map(k => k.name)
  kids.forEach(kid => (children.add(kid), all(family, kid, children)))
  return children
}
const allDescendents = (family, person) => Array.from(all(family, person.name))
export {allDescendents}