Try with:
df["new_email"] = df.apply(lambda x: new_email_column(x["email_first_part"], x["domain"]), axis=1)
As you want to use data in other columns, you cannot use apply() on the "new_email" column (i.e. pandas Series df["new_email"]) as in your original code df["new_email"]).apply(...). You have to use the apply on the the whole DataFrame df (or selected columns with the specific columns you want to use).
You need to add axis=1 to the apply() function so as to work on the column axis (i.e. perform row-wise operation with passing row data with all columns to your apply() function). Without axis=1, you are working on columns one by one where you can only access the row-index rather than column indice/labels.
Using the lambda function allows you to call your custom function new_email_column() without modification of the function. Otherwise, you need to amend the function to include one more parameter for the passed-in row Series).
If you want to better understand this convention of using apply(..., axis=1) and also explore another calling convention with better system performance (execution time), you can refer to this post for further information.