Since I don't know your tables, it is difficult to suggest. But when things like this happens there is all reason to ask: is the query correct? Have you tested this with a smaller data set to verify the query?
As I said, I don't know your tables, but I get the feeling that cus_id is not a unique key in cu_base. And if so, this join:
from
yearcohorts yc
join
custmr_billed ub on yc.cus_id = ub.cus_id
will cause a row explosion. Say that there are 100 rows for a customer. This join will then produce 10000 rows for that customer only. In the final result this may be masked by the GROUP BY, but before that happens you may have filled up tempdb.
I fail to see that there would be any reason to write the yearcohorts CTE this way:
select
cus_id,
min(billed_yr) over (partition by cus_id) as cohortyear
from
custmr_billed
If you write it as
SELECT cus_id, MIN(billed_yr) AS cohortyear
FROM custmr_billed
GROUP BY cus_id
There will be no row explosion in the join in the next CTE.