I have improved on ulf's improvement of stealz' code. I'm pretty sure the last "foreach" adds nothing, so I've removed it, as well as adding a check for string class names (as opposed to objects) to prevent the warning if the class is not found:
<?php
function class_uses_deep($class, $autoload = true) {
  $traits = [];
  do {
    $class_name = is_object($class)? get_class($class): $class;
    if (class_exists($class_name, $autoload)) {
      $traits = array_merge(class_uses($class, $autoload), $traits);
    }
  } while ($class = get_parent_class($class));
  $traits_to_search = $traits;
  while (!empty($traits_to_search)) {
    $new_traits = class_uses(array_pop($traits_to_search), $autoload);
    $traits = array_merge($new_traits, $traits);
    $traits_to_search = array_merge($new_traits, $traits_to_search);
  };
  return array_unique($traits);
}